package com.sec.android.app.myfiles.navigation;

import com.sec.android.app.myfiles.activity.FileListActivity;
import com.sec.android.app.myfiles.facade.cmd.ToSelectModeCmd;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.info.AppFeatures;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.log.SamsungAnalyticsLog;
import com.sec.android.app.myfiles.module.abstraction.AbsContentObserverImp;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.CategoryType;
import com.sec.android.app.myfiles.module.abstraction.FileRecord.StorageType;
import com.sec.android.app.myfiles.module.local.home.HomeFileRecord;
import com.sec.android.app.myfiles.module.local.recent.RecentFileRecord;
import com.sec.android.app.myfiles.module.optimizestorage.OptimizeStorageFileRecord;
import com.sec.android.app.myfiles.module.search.SearchFileRecord;
import com.sec.android.app.myfiles.util.StorageMonitor;

import java.util.ArrayList;

/**
 * This class represent that current state
 *
 * @author jae.bae
 */
public class NavigationInfo {
    private FileRecord mCurRecord;
    private FileRecord mFocusRecord;
    private NavigationMode mNavigationMode;
    private int mProcessId = -1;
    private AbsMyFilesFragment mCurFragment;
    private final ArrayList<AbsContentObserverImp> mContentObserver = new ArrayList<>();
    private int mListPosition;

    private CategoryType mCategoryFilter;
    private String[] mMimeTypeFilter;
    private String[] mExtensionFilter;
    private String mPathFilter;
    private String mPrefixFilter;
    private int mMaxSelectCnt;
    private boolean mIsSearchMode;

    private SamsungAnalyticsLog.ScreenPath mScreenPath;

    private ToSelectModeCmd.SelectModeType mStartWithSelectMode;
    private int mStartSelectionPos = -1;
    private boolean mControlSetSelectedFileBoxVisibilityManually;

    private boolean mShowLoadingView;

    public enum NavigationMode {
        Normal,
        Select_copy_destination,
        Select_move_destination,
        Select_remove_from_private,
        Select_destination_path,
        Select_create_doc_destination,
        Pick_one_file,
        Pick_files,
        Preview_compress_item,
        Optimize_storage_files,
        Select_optimize_storage_backup_destination
    }

    public static NavigationInfo getInstance(NavigationMode mode, FileRecord record) {
        NavigationInfo ret = new NavigationInfo();
        ret.mCurRecord = record;
        ret.mNavigationMode = mode;
        if (record instanceof SearchFileRecord) {
            ret.mIsSearchMode = true;
        }

        return ret;
    }

    /**
     * Create instance using preInfo
     */
    public static NavigationInfo getInstance(NavigationInfo preInfo, FileRecord record) {
        NavigationInfo ret = new NavigationInfo();
        ret.mCurRecord = record;

        if (preInfo != null) {
            ret.mNavigationMode = preInfo.mNavigationMode;
            ret.mMaxSelectCnt = preInfo.mMaxSelectCnt;
            ret.mMimeTypeFilter = preInfo.mMimeTypeFilter;
            ret.mExtensionFilter = preInfo.mExtensionFilter;
            ret.mPathFilter = preInfo.mPathFilter;
            ret.mCategoryFilter = preInfo.mCategoryFilter;
            ret.mScreenPath = preInfo.mScreenPath;

            if (isRotationChangedFromHome(record) && isRotationChangedFromHome(preInfo.getCurRecord())) {
                /*for rotate in home (note)*/
                ret.mIsSearchMode = preInfo.mIsSearchMode;
            }
        } else {
            ret.mNavigationMode = NavigationMode.Normal;
        }

        if (record instanceof SearchFileRecord) {
            ret.mIsSearchMode = true;
        }

        return ret;
    }

    private static boolean isRotationChangedFromHome(FileRecord record) {
        return record instanceof RecentFileRecord || record instanceof HomeFileRecord;
    }

    public StorageType getStorageType() {
        StorageType ret = StorageType.None;
        if (mCurRecord != null) {
            ret = mCurRecord.getStorageType();
        }

        return ret;
    }

    private NavigationInfo() {
        mListPosition = -1;
    }

    public NavigationMode getNavigationMode() {
        return mNavigationMode;
    }

    public NavigationMode setNavigationMode(NavigationMode mode) {
        return mNavigationMode = mode;
    }

    public FileRecord getCurRecord() {
        return mCurRecord;
    }

    public void setCurRecord(FileRecord record) {
        mCurRecord = record;
    }

    public void setCurFragment(AbsMyFilesFragment curFragment) {
        if (curFragment != null) {
            mProcessId = curFragment.getProcessId();
        }
        mCurFragment = curFragment;
    }

    public AbsMyFilesFragment getCurFragment() {
        AbsMyFilesFragment ret = mCurFragment;
        if (ret == null) {
            ret = FileListActivity.searchForCurFragment(mProcessId);
        }
        return ret;
    }

    public void setCurListPosition(int position) {
        mListPosition = position;
    }

    public void setFocusRecord(FileRecord focus) {
        mFocusRecord = focus;
    }

    public FileRecord getFocusRecord() {
        return mFocusRecord;
    }

    public int getCurListPosition() {
        return mListPosition;
    }

    public void setCategoryFilter(CategoryType categoryFilter) {
        mCategoryFilter = categoryFilter;
    }

    public CategoryType getCategoryFilter() {
        return mCategoryFilter;
    }

    public void setMimeTypeFilter(String[] mimeTypeFilter) {
        mMimeTypeFilter = mimeTypeFilter;
    }

    public String[] getMimeTypeFilter() {
        return mMimeTypeFilter;
    }

    public void setExtensionFilter(String[] extensionFilter) {
        mExtensionFilter = extensionFilter;
    }

    public String[] getExtensionFilter() {
        return mExtensionFilter;
    }

    public void setPathFilter(String pathFilter) {
        mPathFilter = pathFilter;
    }

    public String getPathFilter() {
        return mPathFilter;
    }

    public void setPrefixFilter(String prefix) {
        mPrefixFilter = prefix;
    }

    public String getPrefixFilter() {
        return mPrefixFilter;
    }

    public void setMaxSelectCnt(int maxSelectCnt) {
        mMaxSelectCnt = maxSelectCnt;
    }

    public int getMaxSelectCnt() {
        return mMaxSelectCnt;
    }

    public SamsungAnalyticsLog.ScreenPath getScreenPath() {
        return mScreenPath;
    }

    public void setScreenPath(SamsungAnalyticsLog.ScreenPath screenPath) {
        mScreenPath = screenPath;
    }

    public boolean isNormalMode() {
        return mNavigationMode == NavigationMode.Normal;
    }

    public boolean isPickerMode() {
        return mNavigationMode == NavigationMode.Pick_files ||
                mNavigationMode == NavigationMode.Pick_one_file;
    }

    public boolean isSinglePickerMode() {
        return mNavigationMode == NavigationMode.Pick_one_file;
    }

    public boolean isSingleAudioPickerMode() {
        boolean bRet = false;
        if (mNavigationMode == NavigationMode.Pick_one_file) {
            if (mMimeTypeFilter != null) {
                for (String mimeType : mMimeTypeFilter) {
                    bRet = mimeType.startsWith("audio/") || mimeType.equalsIgnoreCase("application/ogg");
                }
            }
        }
        return bRet;
    }

    public boolean isSelectMode() {
        return mNavigationMode == NavigationMode.Preview_compress_item ||
                mNavigationMode == NavigationMode.Optimize_storage_files ||
                mNavigationMode == NavigationMode.Pick_files ||
                mNavigationMode == NavigationMode.Pick_one_file;
    }

    public boolean isSelectDestination() {
        return mNavigationMode == NavigationMode.Select_copy_destination ||
                mNavigationMode == NavigationMode.Select_move_destination ||
                mNavigationMode == NavigationMode.Select_destination_path ||
                mNavigationMode == NavigationMode.Select_remove_from_private ||
                mNavigationMode == NavigationMode.Select_create_doc_destination ||
                mNavigationMode == NavigationMode.Select_optimize_storage_backup_destination;
    }

    public boolean refreshActionMenu() {
        return mNavigationMode == NavigationMode.Select_copy_destination ||
                mNavigationMode == NavigationMode.Select_move_destination ||
                mNavigationMode == NavigationMode.Select_destination_path ||
                mNavigationMode == NavigationMode.Select_remove_from_private ||
                mNavigationMode == NavigationMode.Select_create_doc_destination ||
                mNavigationMode == NavigationMode.Select_optimize_storage_backup_destination||
                mNavigationMode == NavigationMode.Pick_files;
    }

    public boolean isSelectOpDestination() {
        return mNavigationMode == NavigationMode.Select_copy_destination ||
                mNavigationMode == NavigationMode.Select_move_destination ||
                mNavigationMode == NavigationMode.Select_remove_from_private ||
                mNavigationMode == NavigationMode.Select_optimize_storage_backup_destination;
    }

    public boolean isCreateDocument() {
        return mNavigationMode == NavigationMode.Select_create_doc_destination;
    }

    public boolean isRemoveFromPrivate() {
        return mNavigationMode == NavigationMode.Select_remove_from_private;
    }

    public boolean isCompressPreview() {
        return mNavigationMode == NavigationMode.Preview_compress_item;
    }

    public boolean isSelectDestinationPath() {
        return mNavigationMode == NavigationMode.Select_destination_path;
    }

    /**
     * Check Same record & different NavigationMode
     */
    public boolean isNavigationModeChanged(NavigationInfo info) {
        boolean bRet = false;
        if (info != null) {
            if (mNavigationMode != info.mNavigationMode) {
                if (mCurRecord != null && mCurRecord.equals(info.mCurRecord)) {
                    bRet = true;
                }
            }
        }
        return bRet;
    }

    private boolean isPickerFilesWithParam() {
        boolean bRet = false;
        if (mNavigationMode == NavigationMode.Pick_files) {
            if (mMimeTypeFilter != null && mMimeTypeFilter.length > 0) {
                bRet = true;
            }
            if (mCategoryFilter != null) {
                bRet = true;
            }
        }
        return bRet;
    }

    public boolean isLeftPanelDisabled() {
        boolean bRet = false;
        if (getStorageType().equals(StorageType.OptimizeStorage)) {
            bRet = true;
        } else if (AppFeatures.isTabletUIMode()) {
            if (isSinglePickerMode() || isPickerFilesWithParam()) {
                bRet = true;
            }
        } else {
            if (isSelectDestination() || isPickerMode() || isCreateDocument()) {
                bRet = true;
            }
        }
        return bRet;
    }

    public boolean needBottomDetailLayout() {
        boolean ret = true;
        if (getStorageType() == StorageType.OptimizeStorage) {
            if (mCurRecord != null &&
                    ((OptimizeStorageFileRecord) mCurRecord).getOptimizeStorageType() == FileRecord.OptimizeStorageType.Overview) {
                ret = false;
            }
        }
        return ret;
    }

    public boolean needShowCopyMoveBottomDetail() {
        return getStorageType() != StorageType.OptimizeStorage;
    }

    public void setContentObserver(AbsContentObserverImp observer) {
        mContentObserver.add(observer);
    }

    public AbsContentObserverImp getContentObserver(int index) {
        if (getObserverSize() >= index) {
            return mContentObserver.get(index);
        }
        return null;
    }

    public int getObserverSize() {
        Log.d(this, "getObserverSize mContentObserver.size() " + mContentObserver.size());
        return mContentObserver.size();
    }

    public void clearObserver() {
        mContentObserver.clear();
    }

    @Override
    public boolean equals(Object o) {
        boolean bRet = false;
        if (o instanceof NavigationInfo) {
            NavigationInfo cmp = (NavigationInfo) o;
            if (mNavigationMode == cmp.mNavigationMode) {
                if (mCurRecord == cmp.mCurRecord) {
                    bRet = true;
                }
                if (mCurRecord != null && mCurRecord.equals(cmp.mCurRecord)) {
                    bRet = true;
                }
            }
        } else {
            bRet = super.equals(o);
        }

        return bRet;
    }

    @Override
    public int hashCode() {
        int initValue = 631; // randomly chosen prime numbers
        int constant = 2971; // randomly chosen prime numbers

        int nRet = initValue;

        nRet += mCurRecord.hashCode() * constant;
        nRet += mNavigationMode.hashCode() * constant;

        return nRet;
    }

    public boolean needUpdateOptionsMenuAfterLoad() {
        return isPickerMode() || getStorageType() == StorageType.Recent || getStorageType() == StorageType.Downloads;
    }

    public void showLoadingView(boolean show) {
        mShowLoadingView = show;
    }

    public boolean needLoadingView() {
        boolean ret = mShowLoadingView;
        if (mShowLoadingView && mCurRecord != null) {
            StorageType storageType = mCurRecord.getStorageType();
            ret = (storageType == StorageType.Cloud) || (storageType == StorageType.OptimizeStorage) || (storageType == StorageType.Trash);
        }
        return ret;
    }

    public void setStartWithSelectMode(ToSelectModeCmd.SelectModeType selectMode) {
        if (selectMode == null) {
            mStartSelectionPos = -1;
        }
        mStartWithSelectMode = selectMode;
    }

    public ToSelectModeCmd.SelectModeType getStartWithSelectMode() {
        return mStartWithSelectMode;
    }

    public void setStartSelectionPos(int pos) {
        mStartSelectionPos = pos;
    }

    public int getStartSelectionPos() {
        return mStartSelectionPos;
    }

    public boolean getIsSearchMode() {
        return mIsSearchMode;
    }

    public void setIsSearchMode(boolean isSearchMode) {
        mIsSearchMode = isSearchMode;
    }


    public void setControlSelectedFileBoxVisibilityManually(boolean controlManually) {
        mControlSetSelectedFileBoxVisibilityManually = controlManually;
    }

    public boolean controlSelectedFileBoxVisibilityManually() {
        return isSelectOpDestination() && mControlSetSelectedFileBoxVisibilityManually;
    }

    public boolean isUsbStorage() {
        boolean ret = false;
        if (getCurRecord() != null) {
            ret = StorageMonitor.startWithUsbRoot(getCurRecord().getFullPath());
        }

        return ret;
    }

    public boolean isEmptySdCardInfo() {
        return (!StorageMonitor.isSdCardMounted() && StorageMonitor.getExtSDCardPath().equals(getCurRecord().getFullPath()));
    }

}
